package com.sikadwafastdaisfondturbo.pretloan.ui.credit.activity

import android.annotation.SuppressLint
import android.view.View
import android.widget.SeekBar
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.sikadwafastdaisfondturbo.lib_baseadapter.SikadwaOnItemChildClickListener
import com.sikadwafastdaisfondturbo.pretloan.R
import com.sikadwafastdaisfondturbo.pretloan.adapter.AmountAdapter
import com.sikadwafastdaisfondturbo.pretloan.adapter.CreditApplyDaysAdapter
import com.sikadwafastdaisfondturbo.pretloan.adapter.CreditApplyDetailsAdapter
import com.sikadwafastdaisfondturbo.pretloan.analysis.TestAnalysisAddEvent
import com.sikadwafastdaisfondturbo.pretloan.databinding.CreditApplyBinding
import com.sikadwafastdaisfondturbo.pretloan.pro.ProActivity
import com.sikadwafastdaisfondturbo.pretloan.status.StatusRepository
import com.sikadwafastdaisfondturbo.pretloan.utils.BarUtils
import com.sikadwafastdaisfondturbo.pretloan.utils.DensityUtils
import com.sikadwafastdaisfondturbo.pretloan.utils.config.Configs
import com.sikadwafastdaisfondturbo.pretloan.utils.event.EventType
import com.sikadwafastdaisfondturbo.pretloan.utils.helper.ActivityStackHelper
import com.sikadwafastdaisfondturbo.pretloan.utils.http.AppUrls
import com.sikadwafastdaisfondturbo.pretloan.utils.http.AppUrls.addCommonParams
import com.sikadwafastdaisfondturbo.pretloan.utils.http.IHttpCallback
import com.sikadwafastdaisfondturbo.pretloan.utils.log.HHLog
import com.sikadwafastdaisfondturbo.pretloan.utils.rv.GridDecoration
import com.sikadwafastdaisfondturbo.pretloan.utils.rv.LinearDecoration
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import org.json.JSONObject
import java.math.BigDecimal

/**
 * Sikadwa
 * @Author wwdeng
 * @CreateTime: 2024/5/22 17:31
 * @Annotation：贷款申请
 */
class ApplyActivity: ProActivity() {
    lateinit var binding: CreditApplyBinding

    //金额
    private var mAmountAdapter: AmountAdapter? = null
    //老用户可以选择时间
    private var mDaysAdapter: CreditApplyDaysAdapter? = null
    //明细列表
    private var mItemAdapter: CreditApplyDetailsAdapter? = null
    //是否点击申请贷款，只有主动点击申请按钮才会处理总流程刷新通知
    private var isApplyClick = false

    //老客申请金额刻度
    private var mScale = 0
    private var mMinProcess = 0//最小值
    override fun getRootView(): View {
        binding = CreditApplyBinding.inflate(layoutInflater)
        return binding.root
    }

    @Subscribe
    override fun initView() {
        binding.parentLayout.setPadding(0,BarUtils.getStatusBarHeight(),0,0)
        initRefreshLayout()
        initRvAmount()
        initRvDays()
        initRvDetails()

        EventBus.getDefault().register(this)
        //用户状态 流程接口 userType字段判断：NEW 或 OLD
        //NEW 显示正常额度，不显示可选额度和可选时间
        if (isNewUser()){
            binding.newLimitLayout.visibility = View.VISIBLE
            binding.oldLimitLayout.visibility = View.GONE
            binding.oldDaysLayout.visibility = View.GONE
            binding.rvDays.visibility = View.GONE
            binding.newDaysLayout.visibility = View.VISIBLE
        } else {
            binding.newLimitLayout.visibility = View.GONE
            binding.oldLimitLayout.visibility = View.VISIBLE
            binding.oldDaysLayout.visibility = View.VISIBLE
            binding.rvDays.visibility = View.VISIBLE
            binding.newDaysLayout.visibility = View.GONE
        }
    }

    override fun initListener() {
        binding.imgBack.setOnClickListener {
            finish()
        }
        binding.imgKefu.setOnClickListener {
            showKefuDialog("CreditApply Page")
            addEvent(EventType.CLICK.CLICK_CUSTOMER,"CreditApply Page")
        }
        binding.seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
            override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
                // 当进度改变时调用
                val showProcess = progress * mScale + mMinProcess
                binding.textLimitAmount.text = "$showProcess"
            }
            override fun onStartTrackingTouch(seekBar: SeekBar?) {
                // 当用户开始触摸SeekBar（按下）时调用
            }
            override fun onStopTrackingTouch(seekBar: SeekBar?) {
                // 当用户结束触摸SeekBar（抬手）时调用
                loadCreditApplyDataAction()
            }
        })
        //确定
        binding.btnSubmit.setOnClickListener {
            isApplyClick = true
            /**
             * 流程
             * 1、需要先通过流程接口，判断订单状态和申请状态
             * 2、创建贷款申请订单
             * 3、创建贷款申请订单成功后再验证总流程，返回首页显示审核状态
             */
            showLoading()
            //发送更新总流程通知
            EventBus.getDefault().post(Configs.Event.PROCESS_REFRESH)
            addEvent(EventType.CLICK.CLICK_CREDIT_APPLY_CONFIRM,"")
        }
    }

    override fun initData() {
        showLoading()
        loadCreditApplyDataAction()
    }

    /* 初始化刷新 */
    private fun initRefreshLayout() {
        //禁止加载
        binding.refreshLayout.setEnableLoadMore(false)
        binding.refreshLayout.setEnableAutoLoadMore(false)
        binding.refreshLayout.setOnRefreshListener {
            loadCreditApplyDataAction()
        }
        binding.refreshLayout.setOnLoadMoreListener {
            binding.refreshLayout.finishLoadMore()
        }
    }

    /**
     * 金额列表
     */
    private fun initRvAmount(){
        binding.rvAmount.setHasFixedSize(true)
        binding.rvAmount.isNestedScrollingEnabled = false
        binding.rvAmount.isFocusableInTouchMode = false //不需要焦点
        val decoration = DensityUtils.dp2px(14f)
        binding.rvAmount.addItemDecoration(LinearDecoration(0,decoration,0,0))
        val layoutManager = LinearLayoutManager(getContext())
        layoutManager.orientation = RecyclerView.HORIZONTAL
        binding.rvAmount.layoutManager = layoutManager
        mAmountAdapter = AmountAdapter(binding.rvAmount)
        mAmountAdapter!!.setOnItemChildClickListener { parent, childView, position ->
            val item = this.mAmountAdapter!!.getItem(position)
        }
        binding.rvAmount.adapter = mAmountAdapter
    }

    /**
     * 选择days列表
     */
    @SuppressLint("NotifyDataSetChanged")
    private fun initRvDays(){
        binding.rvDays.setHasFixedSize(true)
        binding.rvDays.isNestedScrollingEnabled = false
        binding.rvDays.isFocusableInTouchMode = false //不需要焦点
        val decoration = DensityUtils.dp2px(22f)
        binding.rvDays.addItemDecoration(GridDecoration(3,decoration,false))
        val layoutManager = GridLayoutManager(getContext(),3)
        binding.rvDays.layoutManager = layoutManager
        mDaysAdapter = CreditApplyDaysAdapter(binding.rvDays)
        mDaysAdapter!!.setOnItemChildClickListener { parent, childView, position ->
            val item = this.mDaysAdapter!!.getItem(position)
            if (item.optBoolean("isSelect",false)){
                return@setOnItemChildClickListener
            }
            for (i in 0..<mDaysAdapter!!.itemCount){
                val model = mDaysAdapter!!.getItem(i)
                model.put("isSelect",false)
                if (i == position){
                    model.put("isSelect",true)
                }
            }
            mDaysAdapter!!.notifyDataSetChanged()

            loadCreditApplyDataAction()
        }
        binding.rvDays.adapter = mDaysAdapter
    }

    /**
     * 初始化明细列表
     */
    private fun initRvDetails() {
        binding.rvDetails.setHasFixedSize(true)
        binding.rvDetails.isNestedScrollingEnabled = false
        binding.rvDetails.isFocusableInTouchMode = false //不需要焦点
        binding.rvDetails.layoutManager = LinearLayoutManager(this)
        mItemAdapter = CreditApplyDetailsAdapter(binding.rvDetails)
        binding.rvDetails.adapter = mItemAdapter!!
        binding.rvDetails.itemAnimator = DefaultItemAnimator()
        mItemAdapter!!.setOnItemChildClickListener(SikadwaOnItemChildClickListener { _, childView, position ->
            if (childView.id == R.id.itemLayout) {//切换item

            }
        })
    }

    /**
     * 是否是新用户
     */
    private fun isNewUser(): Boolean{
        val obj = JSONObject(Configs.getSPString(Configs.SPKEY.SIKADWA_PROCESS))
        if (!obj.has("userType")){
            return true
        }
        return obj.optString("userType") == "NEW"
    }

    /**
     * 设置贷款额度预览信息
     */
    fun setCreditApplyData(data: JSONObject) {
//        binding.tvAmountUnit.text = data.optString("currency")
        if (isNewUser()){
            val amountList = arrayListOf<String>()
            val amountString = BigDecimal(data.optString("amount")).stripTrailingZeros().toPlainString()
            for (i in amountString.indices){
                amountList.add(amountString[i].toString())
            }
            mAmountAdapter!!.data = amountList

            binding.textLoanTermDays.text = String.format(getString(R.string.credit_apply_loan_term_days),data.optString("days"))

        } else {
            val amount = BigDecimal(data.optString("amount")).stripTrailingZeros().toPlainString()
            mMinProcess = BigDecimal(data.optString("minAmount")).stripTrailingZeros().toPlainString().toInt()
            val maxAmount = BigDecimal(data.optString("maxAmount")).stripTrailingZeros().toPlainString()
            //颗粒度
            mScale = data.optInt("granularity")

            binding.textLimitAmount.text = amount

            //是否允许修改申请金额，不允许修改则不显示Seekbar
            val chooseAmountFlag = data.optBoolean("chooseAmountFlag",false)
            if (!chooseAmountFlag){
                binding.seekLayout.visibility = View.INVISIBLE
                binding.seekAmountLayout.visibility = View.INVISIBLE
            } else {
                binding.seekLayout.visibility = View.VISIBLE
                binding.seekAmountLayout.visibility = View.VISIBLE

                binding.textMinLimit.text = "$mMinProcess"
                binding.textMaxLimit.text = maxAmount
                //设置最大值
                val maxProcess = (maxAmount.toInt() - mMinProcess) / mScale
                binding.seekBar.max = maxProcess
                //设置当前值
                val showAmount = (amount.toInt() - mMinProcess) / mScale
                binding.seekBar.progress = showAmount
            }

            if (mDaysAdapter!!.itemCount == 0){
                //默认天数
                val defaultDays = data.optString("days")
                val daysArray = data.optJSONArray("daysArray")
                val dayList = arrayListOf<JSONObject>()
                if (daysArray != null) {
                    //如果daysArray中没有defaultDays，需要将defaultDays添加到daysArray列表中
                    var isNeedAdd = true
                    for (i in 0..<daysArray.length()){
                        if (daysArray.optString(i) == defaultDays){
                            isNeedAdd = false
                            break
                        }
                    }
                    if (isNeedAdd){
                        daysArray.put(0,defaultDays)
                    }

                    for (i in 0..<daysArray.length()){
                        val day = daysArray.optString(i)
                        val obj = JSONObject()
                        obj.put("day",day)
                        obj.put("isSelect",day == defaultDays)
                        dayList.add(obj)
                    }
                }
                mDaysAdapter!!.data = dayList
            }
        }

        //明细
        val array = data.optJSONArray("detailItemList")
        val dataList = arrayListOf<JSONObject>()
        for (i in 0..<array.length()){
            dataList.add(array.optJSONObject(i))
        }
        mItemAdapter!!.data = dataList
    }

    /**
     * 获取当前选中的期限
     */
    private fun getSelectDays(): String{
        var days = ""
        if (mDaysAdapter!!.itemCount > 0){
            for (i in 0..<mDaysAdapter!!.itemCount){
                val item = mDaysAdapter!!.getItem(i)
                if (item.optBoolean("isSelect",false)){
                    days = item.optString("day")
                    break
                }
            }
        }
        return days
    }

    /**
     * 订单状态 或 申请状态 验证不通过，需要返回首页显示对应页面
     */
    private fun applyFailed() {
        ActivityStackHelper.finishAllActivity(CreditActivity::class.java)
    }

    /**
     * 更新总流程完成
     */
    @Subscribe(threadMode = ThreadMode.POSTING)
    public fun onRefreshProcessCompleted(event: String){
        HHLog.e("收到总流程刷新完成通知>>>>>>>>>>")
        when(event){
            Configs.Event.PROCESS_REFRESHED -> {//总流程刷新完成
                if (isApplyClick){
                    checkProcess()
                    isApplyClick = false
                }
            }
        }
    }

    /**
     * 从数据中获取用户总流程
     * 流程
     * 1、需要先通过总流程接口，判断订单状态和申请状态
     * 2、创建贷款申请订单
     * 3、创建贷款申请订单成功后再验证总流程，返回首页显示审核状态
     */
    private fun checkProcess(){
        val data = JSONObject(Configs.getSPString(Configs.SPKEY.SIKADWA_PROCESS))
        //1、判断是否存在 订单状态
        if (data.has("orderStatus")){
            val orderStatus = data.optString("orderStatus")
            //待还款 || 放款中 || 申请贷款被拒绝
            if (StatusRepository(null,orderStatus).isRepayNow() || StatusRepository(null,orderStatus).isDisbursing() || StatusRepository(null,orderStatus).isRejected()){
                applyFailed()
                return
            }
        }

        //2、判断是否存在 贷款申请状态
        if (data.has("applyStatus")){
            val applyStatus = data.optString("applyStatus")
            //审核中 || 被拒绝
            if (StatusRepository(applyStatus).isReviewing() || StatusRepository(applyStatus).isRejected()){
                applyFailed()
                return
            }
        }

        //3、创建贷款订单
        onCreateApplyOrderAction()
    }

    /**
     * 贷款申请订单创建成功
     */
    fun createOrderSuccess() {
        //注销事件监听
        EventBus.getDefault().unregister(this)
        //贷款申请成功 - 需要打点
        TestAnalysisAddEvent.addApplyEvent()
        //发送更新总流程通知
        EventBus.getDefault().post(Configs.Event.PROCESS_REFRESH)
        //返回首页
        ActivityStackHelper.finishAllActivity(CreditActivity::class.java)
    }

    /**
     * 获取贷款信息
     */
    private fun loadCreditApplyDataAction(){
        val httpUrl = AppUrls.getHttpUrl(AppUrls.URL.COMMON)
        val params = JSONObject().addCommonParams()
        if (!isNewUser()){//老用户需要走另外的流程
            // 获取可选额度和期限的预览信息
            params.put("path",AppUrls.PATH.CREDIT_APPLY_CUSTOM_LIMIT)
            params.put("amount",binding.textLimitAmount.text.toString())
            if (getSelectDays().isNotEmpty()){
                params.put("days",getSelectDays())
            }
        } else {
            params.put("path",AppUrls.PATH.CREDIT_APPLY)
        }
        postAction(httpUrl,params,object : IHttpCallback{
            override fun onRequestSuccess(data: JSONObject) {
                val obj = data.optJSONObject("obj")
                setCreditApplyData(obj)
            }
            override fun onRequestError(error: JSONObject) {
            }
            override fun onRequestFinish() {
                binding.refreshLayout.finishRefresh()
            }
        })
    }

    /**
     * 创建订单
     */
    private fun onCreateApplyOrderAction(){
        val httpUrl = AppUrls.getHttpUrl(AppUrls.URL.COMMON)
        val params = JSONObject().addCommonParams().apply {
            put("path", AppUrls.PATH.CREDIT_APPLY_ORDER_CREATE)
        }
        if (!isNewUser()){//老用户需要走另外的流程
            params.put("amount",binding.textLimitAmount.text.toString())
            params.put("days",getSelectDays())
        }

        postAction(httpUrl,params,object : IHttpCallback{
            override fun onRequestSuccess(data: JSONObject) {
                createOrderSuccess()
            }
            override fun onRequestError(error: JSONObject) {
            }
            override fun onRequestFinish() {
            }
        })
    }

    override fun onStart() {
        super.onStart()
        addEvent(EventType.PAGE.PAGE_CREDIT_APPLY_START,"")
    }

    override fun onDestroy() {
        super.onDestroy()
        addEvent(EventType.PAGE.PAGE_CREDIT_APPLY_END,"")
        EventBus.getDefault().unregister(this)
    }
}